﻿using OpenTK.Math;

namespace Rekx.Graphics
{
    /// <summary>
    /// A camera is a view in 3d space.
    /// </summary>
    public class Camera
    {
        float aspectRatio;
        float farClip;
        float nearClip;
        float fieldOfView;

        Vector3 eye;
        Vector3 target;

        /// <summary>
        /// Creates camera with the given arguments
        /// </summary>
        /// <param name="aspectRatio">Often Width/height</param>
        /// <param name="znear">The near clipping plane</param>
        /// <param name="zfar">The far clipping plane</param>
        /// <param name="fov">The camera's Field of Vision</param>
        /// <param name="eye">The eye of the camera, i.e. position</param>
        /// <param name="target">The point to look at</param>
        public Camera(float aspectRatio, float znear, float zfar, float fov, Vector3 eye, Vector3 target)
        {
            this.aspectRatio = aspectRatio;
            this.nearClip = znear;
            this.farClip = zfar;
            this.fieldOfView = fov;
            this.eye = eye;
            this.target = target;
        }


        // properties to control the camera

        /// <summary>
        /// The eye-location of the camera
        /// </summary>
        public Vector3 Eye
        {
            get
            {
                return eye;
            }
            set
            {
                eye = value;
            }
        }

        /// <summary>
        /// The target of the camera
        /// </summary>
        public Vector3 Target
        {
            get { return target; }
            set
            {
                target = value;
            }
        }

        /// <summary>
        /// The camera's field of view
        /// </summary>
        public float FieldOfView
        {
            get { return fieldOfView; }
            set
            {
                fieldOfView = value;
            }
        }

        /// <summary>
        /// The cameras aspect ration. Often Width/Height
        /// </summary>
        public float AspectRatio
        {
            get { return aspectRatio; }
            set
            {
                aspectRatio = value;   
            }
        }

        /// <summary>
        /// The near clipping plane
        /// </summary>
        public float NearClip
        {
            get { return nearClip; }
            set 
            {
                nearClip = value; 
            }
        }

        /// <summary>
        /// The far clipping plane
        /// </summary>
        public float FarClip
        {
            get { return farClip; }
            set 
            {
                farClip = value;             
            }
        }


        /// <summary>
        /// Generates and returns a view matrix
        /// </summary>
        public Matrix4 View
        {
            get
            {
                return Matrix4.LookAt(eye, target, Vector3.UnitY);
            }
        }


        /// <summary>
        /// Generates and returns a projection matrix
        /// </summary>
        public Matrix4 Projection
        {
            get
            {
                return Matrix4.Perspective(fieldOfView, aspectRatio, nearClip, farClip);
            }
        }
    }
}
